package kr.or.javacafe.demo.service;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import kr.or.javacafe.demo.domain.RankData;
import kr.or.javacafe.demo.domain.RssData;
import kr.or.javacafe.demo.domain.mongo.AccessLog;
import kr.or.javacafe.demo.domain.mongo.StudyMember;
import kr.or.javacafe.demo.domain.mongo.TwitterRawData;
import kr.or.javacafe.demo.domain.mongo.TwitterWord;
import kr.or.javacafe.demo.domain.rank.Rank;
import kr.or.javacafe.demo.domain.rss.Rss;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.xml.sax.InputSource;




@Service
public class DemoService {

	static Logger logger = LoggerFactory.getLogger(DemoService.class);

	@Autowired
	MongoTemplate mongoTemplate;

	
	public void saveAccessLog(AccessLog objAL) {
		mongoTemplate.insert(objAL);
	}
	
	
	public List<AccessLog> getAccessLog() {
		SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd");
		String today = sdFormat.format(new Date());
		
		Query query = new Query();
		query.addCriteria(Criteria.where("dttm").regex(today));
		query.with(new Sort(Sort.Direction.DESC, "dttm"));
		query.limit(50);
		
		return mongoTemplate.find(query, AccessLog.class);
	}
	
	public void saveStudyMember(StudyMember objSM) {
		mongoTemplate.insert(objSM);
	}
	
	public List<StudyMember> getStudyMember() {
		Query query = new Query();
		query.addCriteria(Criteria.where("sex").regex("male"));
		
		return mongoTemplate.find(query, StudyMember.class);
	}
	

	public long getTwitterWordTotalCount() {
		return mongoTemplate.count(new Query(), TwitterWord.class);
	}
	
	public List<TwitterWord> findBestTwitterWord() {
		Query query = new Query();
		query.with(new Sort(Sort.Direction.DESC, "count"));
		query.limit(5);
		
		return mongoTemplate.find(query, TwitterWord.class);
	}
	
	public List<TwitterWord> findTwitterWord(String word) {
		Query query = new Query();
		query.addCriteria(Criteria.where("word").regex(word));
		query.with(new Sort(Sort.Direction.ASC, "word"));
		query.limit(100);
		
		return mongoTemplate.find(query, TwitterWord.class);
	}
	
	
	
	
	
	
	public long getTwitterRawDataTotalCount() {
		return mongoTemplate.count(new Query(), TwitterRawData.class);
	}
	
	public List<TwitterRawData> findTwitterRawData(String word) {
		Query query = new Query();
		query.addCriteria(Criteria.where("text").regex(word));
		query.with(new Sort(Sort.Direction.DESC, "createdAt"));
		query.limit(100);
		
		return mongoTemplate.find(query, TwitterRawData.class);
	}
	
	
	
	
	
	
	
	public void saveTwitterDataFromHadoopFile() {		
		String strLine = "";
		
		try {
			FileReader fr = new FileReader("C:\\temp_test\\part-r-00000");
			BufferedReader br = new BufferedReader(fr);
			
			String[] arrTemp;
			TwitterWord tWord = new TwitterWord();
			
			int i=1;
			while ((strLine = br.readLine()) != null) {
				if (i%100 == 0) {
					System.out.println(". " + i);
				} else {
					System.out.print(".");
				}
				
				try {
					arrTemp = strLine.split("\\t");

					tWord = new TwitterWord();
					tWord.setWord(arrTemp[0].trim());
					tWord.setCount(arrTemp[1].trim());
					
					mongoTemplate.insert(tWord);
					
				} catch (Exception ex) {
					//ex.printStackTrace();
					System.out.println("Line No [" + i + "] " + strLine);
					System.out.println(ex.getMessage());
				}
				
				i++;
			}
			
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	
	public void saveTwitterRawDataFromTwitterFile() {		
		String strLine = "";
		
		try {
			FileReader fr = new FileReader("C:\\temp_test\\twitter.txt");
			BufferedReader br = new BufferedReader(fr);
			
			ObjectMapper om = new ObjectMapper();
			Map<String, Object> objTempMap;
			Map<String, Object> objTempUserMap;
			
			String[] arrTemp;
			TwitterRawData tRaw = new TwitterRawData();
			
			int i=1;
			while ((strLine = br.readLine()) != null) {
				if (i%100 == 0) {
					System.out.println(". " + i);
				} else {
					System.out.print(".");
				}
				
				try {
					objTempMap = om.readValue(strLine, new TypeReference<Map<String, Object>>() {});
					
					tRaw = new TwitterRawData();
					tRaw.setTwitterId(new Long((Long)objTempMap.get("id")).toString());
					tRaw.setCreatedAt(new Long((Long)objTempMap.get("createdAt")).toString());
					tRaw.setText((String)objTempMap.get("text"));

					objTempUserMap = (Map<String, Object>)objTempMap.get("user");

					try {
						tRaw.setUserId(new Integer((Integer)objTempUserMap.get("id")).toString());
					} catch (ClassCastException cce) {
						tRaw.setUserId(new Long((Long)objTempUserMap.get("id")).toString());
					}
					tRaw.setName((String)objTempUserMap.get("name"));
					tRaw.setProfileImageURL((String)objTempUserMap.get("profileImageURL"));
					tRaw.setLang((String)objTempUserMap.get("lang"));
					
					mongoTemplate.insert(tRaw);
					
				} catch (Exception ex) {
					//ex.printStackTrace();
					System.out.println("Line No [" + i + "] " + strLine);
					System.out.println(ex.getMessage());
				}
				
				i++;
			}
			
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	public RssData getRssResult(RssData naverDiary) {
		try {
			
			String query = naverDiary.getServiceKey();

			HttpClient httpClient = new HttpClient();
			HttpMethod method = new GetMethod(query);
			
			int status = httpClient.executeMethod(method);
			if (200 == status) {
				StringBuffer resultMessage = new StringBuffer();
				
				BufferedReader br = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(), "utf-8"));
				String line;
			    while ((line = br.readLine()) != null) {
			    	resultMessage.append(line);
			    }
			    br.close();
				
				String strXML = resultMessage.toString();

				logger.debug("======================================================================================");
				logger.debug(query);
				logger.debug("======================================================================================");
				logger.debug(strXML);
				logger.debug("======================================================================================");

						
				try {
					JAXBContext context = JAXBContext.newInstance(RssData.class); //JAXB�� XMLŸ���� �ԷµǸ� �Ĺ�)
					Unmarshaller ums = context.createUnmarshaller();

					Rss objResult = (Rss)ums.unmarshal(new InputSource(new StringReader(strXML)));
					
					naverDiary.setResult(objResult);
					
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return naverDiary;
	}
	
	
	
	
	
	public RankData getRankResult(RankData rank) {
		try {
			
			String query = rank.getServiceKey();

			HttpClient httpClient = new HttpClient();
			HttpMethod method = new GetMethod(query);
			
			int status = httpClient.executeMethod(method);
			if (200 == status) {
				StringBuffer resultMessage = new StringBuffer();
				
				BufferedReader br = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(), "utf-8"));
				String line;
			    while ((line = br.readLine()) != null) {
			    	resultMessage.append(line);
			    }
			    br.close();
				
				String strXML = resultMessage.toString();

				logger.debug("======================================================================================");
				logger.debug(query);
				logger.debug("======================================================================================");
				logger.debug(strXML);
				logger.debug("======================================================================================");

						
				try {
					JAXBContext context = JAXBContext.newInstance(RankData.class);
					Unmarshaller ums = context.createUnmarshaller();

					Rank objResult = (Rank)ums.unmarshal(new InputSource(new StringReader(strXML)));
					
					rank.setResult(objResult);
					
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return rank;
	}
	
	
	
}
























